﻿using Sasc.PV.BLL.Annotation;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Sasc.PV.BLL
{
    public static class CheJianUtils
    {
        #region Static
        static readonly List<CheJianStorageInfo> CheJianStorages = new List<CheJianStorageInfo>();
        static readonly Dictionary<Type, string> CheJianDictionary = new Dictionary<Type, string>();
        static readonly Dictionary<Type, string> CheJianGongXuDictionary = new Dictionary<Type, string>();

        static CheJianUtils()
        {
            var allGongXuStorages = new List<CheJianGongXuStorageInfo>();

            var allAssemblies = AppDomain.CurrentDomain.GetAssemblies();
            foreach (var assembly in allAssemblies)
            {
                try
                {
                    var allTypes = assembly.GetTypes();

                    #region Iterate the Types
                    foreach (var type in allTypes)
                    {
                        if (type.IsClass)
                        {
                            if (typeof(ICheJianManagement).IsAssignableFrom(type))
                            {
                                var cheJianAttr = type.GetCustomAttributes(typeof(CheJianAttribute), false).Cast<CheJianAttribute>().FirstOrDefault();
                                if (cheJianAttr != null)
                                {
                                    // 是车间
                                    CheJianStorages.Add(new CheJianStorageInfo
                                    {
                                        CheJianName = cheJianAttr.Name,
                                        CheJianType = type
                                    });
                                    CheJianDictionary[type] = cheJianAttr.Name;
                                }
                            }
                            else if (typeof(ICheJianGongXu).IsAssignableFrom(type))
                            {
                                var gongXuAttr = type.GetCustomAttributes(typeof(GongXuAttribute), false).Cast<GongXuAttribute>().FirstOrDefault();
                                if (gongXuAttr != null)
                                {
                                    // 是工序
                                    allGongXuStorages.Add(new CheJianGongXuStorageInfo
                                    {
                                        GongXuName = gongXuAttr.Name,
                                        GongXuType = type,
                                        CheJianType = gongXuAttr.CheJianType
                                    });
                                    CheJianGongXuDictionary[type] = gongXuAttr.Name;
                                }
                            }
                        }
                    }
                    #endregion

                    #region Map GongXu to CheJian
                    foreach (var gongxuStorage in allGongXuStorages)
                    {
                        var cheJianStorage = CheJianStorages.FirstOrDefault(c => c.CheJianType == gongxuStorage.CheJianType);
                        if (cheJianStorage != null)
                            cheJianStorage.GongXuList.Add(gongxuStorage);
                    }
                    #endregion

                }
                catch (Exception e)
                { 
                }
            }
        }
        #endregion

        #region Internal Class
        class CheJianStorageInfo
        {
            public CheJianStorageInfo()
            {
                GongXuList = new List<CheJianGongXuStorageInfo>();
            }

            internal string CheJianName { get; set; }
            internal Type CheJianType { get; set; }

            internal List<CheJianGongXuStorageInfo> GongXuList { get; set; }
        }
        class CheJianGongXuStorageInfo
        {
            internal string GongXuName { get; set; }
            internal Type GongXuType { get; set; }
            internal Type CheJianType { get; set; }
        }
        #endregion

        #region 获取车间或者工序名称
        public static string GetCheJianName(Type cheJianType)
        {
            return CheJianDictionary.ContainsKey(cheJianType) ? CheJianDictionary[cheJianType] : string.Empty;
        }

        public static string GetCheJianName<TCheJian>()
            where TCheJian :class, ICheJianManagement
        {
            return GetCheJianName(typeof(TCheJian));
        }

        public static string GetCheJianGongXuName(Type cheJianGongXuType)
        {
            return CheJianGongXuDictionary.ContainsKey(cheJianGongXuType) ? CheJianGongXuDictionary[cheJianGongXuType] : string.Empty;
        }

        public static string GetCheJianGongXuName<TCheJianGongXu>()
            where TCheJianGongXu : ICheJianGongXu
        {
            return GetCheJianGongXuName(typeof(TCheJianGongXu));
        }
        #endregion

        #region 获取车间或者工序类型
        public static Type GetCheJianType(string cheJianName)
        {
            return CheJianStorages.Where(c => c.CheJianName.Equals(cheJianName)).Select(c => c.CheJianType).FirstOrDefault();
        }

        public static Type GetCheJianGongXuType(string cheJianName, string gongXuName)
        {
            return CheJianStorages.Where(c => c.CheJianName.Equals(cheJianName)).SelectMany(c => c.GongXuList).Where(c => c.GongXuName.Equals(gongXuName)).Select(c=>c.GongXuType).FirstOrDefault();
        }
        #endregion
    }

}
